package cn.btks.zuulserver.jwt;

import cn.btks.zuulserver.dto.Role;
import cn.btks.zuulserver.dto.User;
import cn.btks.zuulserver.util.JwtUtil;
import com.netflix.zuul.context.RequestContext;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 它能够确保在一次请求中只通过一次filter，而需要重复的执行
 * @author 26612
 */
@Slf4j
@Component
public class JwtTokenFilter extends OncePerRequestFilter {

    @SneakyThrows
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String url = String.valueOf(request.getRequestURL());
        log.info("URL:" + url);
        String[] split = url.split("/");
        if(split != null && split.length > 0){
            String urlItem = split[split.length - 1];
            if(urlItem.equals("doLogin") || url.contains("iserver")){
                filterChain.doFilter(request, response);
            }
        }
        String token = request.getHeader("token");
        //获取token，并且解析token，如果解析成功，则放入 SecurityContext
        if (token != null) {
            try {
                User authUser = JwtUtil.parseToken(token);

                //解析成功
                if (SecurityContextHolder.getContext().getAuthentication() == null) {
                    //我们依然使用原来filter中的token对象
                    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(authUser,
                            null, authUser.getAuthorities());

                    SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);

                    RequestContext requestContext = RequestContext.getCurrentContext();
                    requestContext.addZuulRequestHeader("token", token);
                }
            } catch (Exception e) {
                logger.info("解析失败，可能是伪造的或者该token已经失效了。");
            }
        }
        filterChain.doFilter(request, response);
    }
}
